package com.ipan.weixin.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.entity.BasicHttpEntity;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.FileEntity;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.SerializableEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ipan.weixin.WxConfiguration;

/**
 * 微信HTTP工具类
 * 
 * @author iPan
 * @version 2013-12-29
 */
public class WxHttpUtils {

	private static Logger logger = LoggerFactory.getLogger(WxHttpUtils.class);
	public static final ContentType DEFAULT_TEXT_HTML = ContentType.create("text/html", Consts.UTF_8);
    public static final ContentType DEFAULT_TEXT_PLAIN = ContentType.create("text/plain", Consts.UTF_8);
    public static final ContentType DEFAULT_TEXT_XML = ContentType.create("text/xml", Consts.UTF_8);

	public static void main(String[] args) throws Exception {
		List<Header> headers = new ArrayList<Header>();
		headers.add(new BasicHeader(HttpHeaders.EXPIRES, System.currentTimeMillis() + 1800 * 1000 + ""));
		headers.add(new BasicHeader(HttpHeaders.CACHE_CONTROL, "private, max-age=" + 1800));
		// get method
//		System.out.println(get("http://127.0.0.1:8080/index.html", headers));
		
		// post method
		HttpEntity entity = createStringEntity("<xml><name>小张</name></xml>", DEFAULT_TEXT_XML);
		System.out.println(post("http://127.0.0.1:8080/index.html", headers, entity));
	}
	
	// -- http get -- //
	public static String get(String uri) {
		return get(uri, null);
	}
	public static String get(String uri, List<Header> headers) {
		String result = null;
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse httpResponse = null;
		try {
			httpClient = HttpClients.createDefault();
			HttpUriRequest httpGet = new HttpGet(uri);
			if (headers != null && headers.size() > 0) {
				for (Header header : headers) {
					httpGet.addHeader(header);
				}
			}
			httpResponse = httpClient.execute(httpGet);
			logger.info("http status: {}", httpResponse.getStatusLine());
			if (httpResponse.getEntity() != null) {
				result = EntityUtils.toString(httpResponse.getEntity());
			}
		} catch (Exception e) {
			logger.warn("执行http get方法出错.", e);
		} finally {
			HttpClientUtils.closeQuietly(httpResponse);
			HttpClientUtils.closeQuietly(httpClient);
		}
		return result;
	}
	
	// -- http post -- //
	public static String post(String uri) {
		return post(uri, null, null);
	}
	public static String post(String uri, List<Header> headers) {
		return post(uri, headers, null);
	}
	public static String post(String uri, List<Header> headers, HttpEntity entity) {
		String result = null;
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse httpResponse = null;
		try {
			httpClient = HttpClients.createDefault();
			HttpPost httpPost = new HttpPost(uri);
			if (headers != null && headers.size() > 0) {
				for (Header header : headers) {
					httpPost.addHeader(header);
				}
			}
			if (entity != null) {
				httpPost.setEntity(entity);
			}
			httpResponse = httpClient.execute(httpPost);
			logger.info("http status: {}", httpResponse.getStatusLine());
			if (httpResponse.getEntity() != null) {
				result = EntityUtils.toString(httpResponse.getEntity());
			}
		} catch (Exception e) {
			logger.warn("执行http post方法出错.", e);
		} finally {
			HttpClientUtils.closeQuietly(httpResponse);
			HttpClientUtils.closeQuietly(httpClient);
		}
		return result;
	}
	
	// -- create BasicHttpEntity -- //
	public static HttpEntity createBasicHttpEntity(InputStream content, long length) {
		BasicHttpEntity entity = new BasicHttpEntity();
		entity.setContent(content);
		entity.setContentLength(length);
		return entity;
	}
	
	// -- create ByteArrayEntity -- //
	public static HttpEntity createByteArrayEntity(byte[] b, ContentType contentType) {
		return new ByteArrayEntity(b, contentType);
	}
	public static HttpEntity createByteArrayEntity(byte[] b, int off, int len, ContentType contentType) {
		return new ByteArrayEntity(b, off, len, contentType);
	}
	public static HttpEntity createByteArrayEntity(byte[] b) {
		return new ByteArrayEntity(b);
	}
	public static HttpEntity createByteArrayEntity(byte[] b, int off, int len) {
		return new ByteArrayEntity(b, off, len);
	}
	
	// -- create StringEntity -- //
	public static HttpEntity createStringEntity(String string, ContentType contentType) {
		return new StringEntity(string, contentType);
	}
	public static HttpEntity createStringEntity(String string, String charsetName) {
		Charset charset = Charset.forName(charsetName);
		return new StringEntity(string, charset);
	}
	public static HttpEntity createStringEntity(String string, Charset charset) {
		return new StringEntity(string, charset);
	}
	
	// -- create InputStreamEntity -- //
	public static HttpEntity createInputStreamEntity(InputStream instream, long length, ContentType contentType) {
		return new InputStreamEntity(instream, length, contentType);
	}
	public static HttpEntity createInputStreamEntity(InputStream instream, long length) {
		return new InputStreamEntity(instream, length);
	}
	
	// -- create FileEntity -- //
	public static HttpEntity createFileEntity(File file, ContentType contentType) {
		return new FileEntity(file, contentType);
	}
	public static HttpEntity createFileEntity(File file) {
		return new FileEntity(file);
	}
	
	// -- create SerializableEntity -- //
	public static HttpEntity createSerializableEntity(Serializable ser, boolean bufferize) throws IOException {
		return new SerializableEntity(ser, bufferize);
	}
	public static HttpEntity createSerializableEntity(Serializable ser) {
		return new SerializableEntity(ser);
	}
	
	// -- create ContentType -- //
	public static ContentType createContentType(String mimeType, String charset) {
		return ContentType.create(mimeType, charset);
	}
	
	// -- 从流中读取文本内容 -- //
	public static String readTextBody(InputStream in) {
		return readTextBody(in, WxConfiguration.getInstance().getEncode());
	}
	public static String readTextBody(InputStream in, String encode) {
		if (in == null) {
			return null;
		}
		
		BufferedReader reader = null;
		StringBuilder buf = new StringBuilder();
		try {
			reader = new BufferedReader(new InputStreamReader(in, encode));
			String line = null;
			while ((line = reader.readLine()) != null) {
				buf.append(line);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e) {
				}
			}
		}
		return buf.toString();
	}
	
}
